package com.xialuo.study;

import com.xialuo.study.agent.ReactAgent;
import com.xialuo.study.tools.DateTimeTool;
import com.xialuo.study.tools.MathTool;
import com.xialuo.study.tools.SearchTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbacks;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import jakarta.annotation.Resource;
import java.util.List;

/**
 * 基于langGraph4j的reactAgent实现
 */
@SpringBootApplication(exclude = {
        com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeAutoConfiguration.class
})
@Slf4j
public class ReactAgentApplication implements CommandLineRunner {
    @Resource
    private ChatModel chatModel;

    @Resource
    private SearchTool searchTool;

    @Resource
    private MathTool mathTool;

    @Resource
    private DateTimeTool dateTimeTool;

    /**
     * 应用程序入口方法
     *
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        SpringApplication.run(ReactAgentApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("启动基于langGraph4j的reactAgent服务");
        ToolCallback[] toolCallbacks = ToolCallbacks.from(dateTimeTool, mathTool, searchTool);

        String systemText = """
                Answer the following questions as best you can.
                                
                Important: If the user's question contains relative time expressions (like "today", "tomorrow", "next week"), 
                you must first use the DateTime tool to get the specific date before proceeding with other actions.
                                
                Use the following format:
                Question: the input question you must answer
                Thought: you should always think about what to do
                Action: the action to take
                Thought: I now know the final answer
                Final Answer: the final answer to the original input question
                                                                
                Begin!
                """;

        ReactAgent agent = ReactAgent
                .builder()
                .chatClient(
                        ChatClient.builder(chatModel)
                                .defaultOptions(OpenAiChatOptions
                                                        .builder()
                                                        .internalToolExecutionEnabled(false)
                                                        .build()
                                )
                                .defaultTools(toolCallbacks)
                                .build()
                )
                .name("reactAgent")
                .prompt(systemText)
                .tools(List.of(toolCallbacks))
                .build();
        String answer = agent.invoke("北京今天天气的最高温的平方根是多少?");
        log.info(answer);
    }
}
